package edu.ncsu.csc.sensors;


import com.sun.spot.sensorboard.EDemoBoard;
import com.sun.spot.sensorboard.EDemoController;
import com.sun.spot.sensorboard.io.IIOPin;
import com.sun.spot.sensorboard.io.IInputPin;
import com.sun.spot.sensorboard.io.IInputPinListener;
import com.sun.spot.util.Queue;


public class RainGaugeSensor implements Sensor, IInputPinListener {
	private static final long EXPIRE_TIME_IN_MILLIS = 10*1000;//300 * 1000; // Readings expire after 5 minutes
	
	private boolean isHigh = false;
	private Queue readings = new Queue();
	
	public RainGaugeSensor() {
		EDemoController econt = EDemoBoard.getInstance().getEDemoController();
		IIOPin pin = econt.getIOPins()[3];
		pin.setAsOutput(false);
		pin.addIInputPinListener(this);
		System.out.println("Pin listener registered");
	}
	
	public char getValue() {
		short val = calcTipsPerHour();
		return (char)val;
	}
	
	private synchronized short calcTipsPerHour() {
		int size = readings.size();
		long curTime = System.currentTimeMillis();
		
		long firstTime = Long.MAX_VALUE;
		long lastTime = 0;
		Queue temp = new Queue();
		while (!readings.isEmpty()){
			Long timestamp = (Long)readings.get();
			
			if (curTime - timestamp.longValue() < EXPIRE_TIME_IN_MILLIS) {
				if (timestamp.longValue() < firstTime) firstTime = timestamp.longValue();
				if (timestamp.longValue() > lastTime) lastTime = timestamp.longValue();
				temp.put(timestamp);				
			} // else the reading will be dropped from the queue, since it isn't reinserted
		}
		readings = temp;
		
		if (lastTime <= firstTime) return 0;
		
		int numReadings = readings.size();
		int timespan = (int)(lastTime - firstTime);

		short tipsPerHour = (short)((numReadings - 1) * 60 * 60 * 1000 / timespan);
		
		System.out.println("Number of readings: " + numReadings);
		System.out.println("Timespan: " + timespan);
		System.out.println("Tips/hour: " + tipsPerHour);
		
		return tipsPerHour;
	}

	public synchronized void pinSetHigh(IInputPin arg0) {
		if (isHigh) return;
		readings.put(new Long(System.currentTimeMillis()));
		isHigh = true;
		System.out.println("TIP!");
	}
	public synchronized void pinSetLow(IInputPin arg0) {
		isHigh = false;
	}
}
